package softswitch.ws;


import java.util.Date;

import javax.ejb.EJB;
import javax.ejb.Stateless;

import pbx.model.Cdr;
import pbx.ws.PbxWS;
import security.model.Organization;
import security.service.SecurityService;
import softswitch.model.CallDetail;
import softswitch.model.Circuit;
import softswitch.model.Plan;
import softswitch.model.PlanDetail;
import softswitch.model.Provider;
import softswitch.model.ProviderRate;
import softswitch.model.Route;
import softswitch.model.RoutePrefix;
import softswitch.service.CallDetailService;
import softswitch.service.CallSummaryRouteGroupService;
import softswitch.service.PackageSummaryService;
import softswitch.service.ProviderRateService;
import softswitch.service.ProviderService;
import util.DateUtil;

@Stateless
public class CdrProcessService {
	
	@EJB
	SecurityService securityService;
	
	@EJB
	PbxWS pbxWS;
	
	@EJB
	SoftswitchService softswitchService;
	
	@EJB
	CallDetailService callDetailService;
	
	@EJB
	ProviderService providerService;
	
	@EJB
	ProviderRateService providerRateService;
	
	@EJB
	PackageSummaryService packageSummaryService;
	
	@EJB
	CallSummaryRouteGroupService callSummaryRouteGroupService;
	

	
	DateUtil  dateUtil = new DateUtil();
	CallLogger callLogger = new CallLogger();
	
	
	public void reprocessByMonth(Integer year, Integer month, Circuit circuit) {	
		callDetailService.deleteByMonth(year, month, circuit);
		packageSummaryService.deleteByMonth(year, month, circuit);
		callSummaryRouteGroupService.deleteByMonth(year, month, circuit);
    	if(circuit!=null){
    		pbxWS.changeCdrBilledStatisByMonth(year, month, null, circuit.getCode().intValue());
    	}
    	else{
    		pbxWS.changeCdrBilledStatisByMonth(year, month, null, null);
    	}
    	
    }
    
	public CallDetail process(Cdr cdr) { 
		
		String accountcode = cdr.getAccountcode();
		
		String uniqueid = cdr.getUniqueid();
		String src = cdr.getSrc();
		String dst = cdr.getDst();
		String clid = cdr.getClid();
		String dcontext = cdr.getDcontext();
		String disposition = cdr.getDisposition();
		Double billsec = cdr.getBillsec();		
		Date answer = cdr.getAnswer();
		
		
		CallDetail calldetail = new CallDetail();
		calldetail.setDestination(dst);
				
				
		if(! ( disposition.equals("ANSWERED") || disposition.equals("ANSWER") ) ){
			callLogger.calllog(calldetail, "DEBUG", "calldetailJOB", "Process No Complete Call");
			pbxWS.setCdrStatus(uniqueid,true);
			return null;
		}
		
		if(billsec == 0){
			callLogger.calllog(calldetail, "DEBUG", "calldetailJOB", "Call With Zero Time");
			pbxWS.setCdrStatus(uniqueid,true);
			return null;
		}
		
		if(accountcode == null) {
			callLogger.calllog(calldetail, "DEBUG", "calldetailJOB", "This CDR dont have accountcode");
			pbxWS.setCdrStatus(uniqueid,true);
			return null;
		}
		
		if(accountcode.equals("")) {
			callLogger.calllog(calldetail, "DEBUG", "calldetailJOB", "This CDR dont have accountcode");
			pbxWS.setCdrStatus(uniqueid,true);
			return null;
		}
		
		callLogger.calllog(calldetail, "DEBUG", "calldetailJOB", "Processing CDR");
		
		if(dcontext.equals("inbound")) {
			callLogger.calllog(calldetail, "DEBUG", "calldetailJOB", "Process Inbound Call");
			pbxWS.setCdrStatus(uniqueid,true);
			return null;
		}
		
		Long circuitcode = Long.parseLong(accountcode);
		Circuit circuit = softswitchService.getCircuitByCode(circuitcode);
		if(circuit==null){
			callLogger.calllog(calldetail, "DEBUG", "calldetailJOB", "No Circuit Code Found "+ circuitcode);
			pbxWS.setCdrStatus(uniqueid,false);
			return null;
		}

		
		RoutePrefix routeprefix = softswitchService.getRoutePrefixByDestination(dst);
		if(routeprefix==null){
			callLogger.calllog(calldetail, "DEBUG", "calldetailJOB", "No Route for destination " + dst);
			pbxWS.setCdrStatus(uniqueid,false);
			return null;
		}
		
		callLogger.calllog(calldetail, "DEBUG", "calldetailJOB", "This Call has a Route and Prefix");
		Route route = routeprefix.getRoute();
	
		
		Plan plan = circuit.getPlan();
		PlanDetail plandetail = softswitchService.getPlanDetailByPlanRoute(plan, routeprefix.getRoute());							
		if(plandetail == null){
			callLogger.calllog(calldetail, "DEBUG", "calldetailJOB", "No PlanDetail for Destination " + dst);
			pbxWS.setCdrStatus(uniqueid,false);
			return null;
		}
		
		callLogger.calllog(calldetail, "DEBUG", "calldetailJOB", "This Call has a valid Plan");
		
		
		//Time Operations
		Integer block = plandetail.getBlock();
		Integer chunk = 0;
		if(billsec <= block){
			chunk = 1;
		}
		else{
			chunk = (int) Math.ceil(billsec/block);
		}
		Integer seconds = chunk * block;		
		Double minutes = seconds.doubleValue()/60;
		
		//Cost Operations
		Double buycost = 0.0;	
		String providerName = cdr.getUserfield();
		Provider provider = providerService.getByName(providerName);
		if(provider==null){
			callLogger.calllog(calldetail, "ERROR", "calldetailJOB", "This call dont have provider");
			return null;
		}
		ProviderRate providerRate = providerRateService.getByRoute(provider, route);		
		if(providerRate==null){
			callLogger.calllog(calldetail, "ERROR", "calldetailJOB", "This provider dont have cost of this route");
			return null;
		}
		Double buyrate = providerRate.getRate();
		buycost = buyrate * minutes;
		buycost = Math.round( buycost * 10000.0 ) / 10000.0;
		
		//Price Operations
		Double sellrate = plandetail.getRate();
		sellrate = Math.round( sellrate * 1000.0 ) / 1000.0;
		Double sellcost = sellrate * minutes;
		sellcost = Math.round( sellcost * 10000.0 ) / 10000.0;
		
		Organization organization = securityService.getOrganizationById(circuit.getOrganization_id());

		//Debuger
		callLogger.calllog(calldetail, "DEBUG", "calldetailJOB", "Organization: " + organization.getName());
		callLogger.calllog(calldetail, "DEBUG", "calldetailJOB", "Circuit: " + circuit.getName() + " "+circuit.getCode());
		callLogger.calllog(calldetail, "DEBUG", "calldetailJOB", "CallID: " + uniqueid);
		callLogger.calllog(calldetail, "DEBUG", "calldetailJOB", "CallDate: " + answer);
		callLogger.calllog(calldetail, "DEBUG", "calldetailJOB", "Route:  " + route.getName());
		callLogger.calllog(calldetail, "DEBUG", "calldetailJOB", "Operator: " + route.getOperator().getName());
		callLogger.calllog(calldetail, "DEBUG", "calldetailJOB", "Country: " + route.getCountry().getName());
		callLogger.calllog(calldetail, "DEBUG", "calldetailJOB", "Provider: " + provider.getName());
		
		callLogger.calllog(calldetail, "DEBUG", "calldetailJOB", "Time in Seconds: " + billsec);
		callLogger.calllog(calldetail, "DEBUG", "calldetailJOB", "Plan Billing Block: " + block);
		callLogger.calllog(calldetail, "DEBUG", "calldetailJOB", "Billing Chunk: " + chunk);
		callLogger.calllog(calldetail, "DEBUG", "calldetailJOB", "Rounded Time in Seconds:" + seconds);
		callLogger.calllog(calldetail, "DEBUG", "calldetailJOB", "Time in Minutes:" + minutes);
		callLogger.calllog(calldetail, "DEBUG", "calldetailJOB", "Buy Rate: " + buyrate);
		callLogger.calllog(calldetail, "DEBUG", "calldetailJOB", "Sell Rate: " + sellrate);
		callLogger.calllog(calldetail, "DEBUG", "calldetailJOB", "Buy Cost: "+ buyrate);
		callLogger.calllog(calldetail, "DEBUG", "calldetailJOB", "Sell Price: " + sellrate);
		
		CallDetail callDetail = new CallDetail();
		callDetail.setUniqueid(uniqueid);
		callDetail.setSource(src);
		callDetail.setDestination(dst);
		callDetail.setContext(dcontext);
		callDetail.setCallerid(clid);
		callDetail.setDisposition(disposition);
		callDetail.setTime(seconds);
		callDetail.setBuyrate(buyrate);
		callDetail.setSellrate(sellrate);
		callDetail.setBuycost(buycost);
		callDetail.setSellcost(sellcost);
		callDetail.setCalldate(answer);
		callDetail.setCircuit(circuit);
		callDetail.setRoute(route);
		callDetail.setProvider(provider);
		
		if(callDetailService.getByUniqueId(uniqueid) == null){
			System.out.println("UNIQUEID NOT FOUND");
			callDetail = callDetailService.save(callDetail);
			pbxWS.setCdrStatus(uniqueid,true);
		}
		else{
			System.out.println("UNIQUEID DUPLICATED");
			callDetail = null;
		}
		
		
		return callDetail;
		
	}//processCDR()


}
